// 节流
export function throttle(fn, delay) {
    let timer = null;
    return function () {
        if (timer) {
            return;
        }
        timer = setTimeout(() => {
            //执行操作(使用apply重新绑定this的指向)
            try {
                fn.apply(this, arguments);
                timer = null;
            } catch (e) {
                console.error(e)
            }
        }, delay)
    }
}

/**
 * 防抖
 * @param fn {Function}   实际要执行的函数
 * @param delay {Number}  延迟时间，也就是阈值，单位是毫秒（ms）
 * @return {Function}     返回一个“去弹跳”了的函数
 */
export function debounce(fn, delay) {
    let timer;
    return function () {

        let context = this
        let args = arguments

        clearTimeout(timer)

        timer = setTimeout(function () {
            fn.apply(context, args)
        }, delay)
    }
}

export function randomNum(minNum, maxNum) {
    switch (arguments.length) {
        case 1:
            return parseInt(Math.random() * minNum + 1, 10);
            break;
        case 2:
            return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
            break;
        default:
            return 0;
            break;
    }
}

export function randomString(e) {
    e = e || 32;
    var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
        a = t.length,
        n = "";
    for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
    return n
}

/**
 * Parse the time to string 格式化时间戳
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0) {
        return null
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
    let date
    if (typeof time === 'undefined' || time === null || time === 'null') {
        return ''
    } else if (typeof time === 'object') {
        date = time
    } else {
        if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
            time = parseInt(time)
        }
        if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000
        }
        date = new Date(time)
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
    const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
        let value = formatObj[key]
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') {
            return ['日', '一', '二', '三', '四', '五', '六'][value]
        }
        if (result.length > 0 && value < 10) {
            value = '0' + value
        }
        return value || 0
    })
    return time_str
}

/**
 * 获取滚动条宽度
 * @returns {number}
 */
export function getScrollbarWidth() {
    let scrollDiv = document.createElement('div');
    scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'
    document.body.appendChild(scrollDiv)
    let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
    document.body.removeChild(scrollDiv)
    return scrollbarWidth
}

/**
 * 隐藏滚动条
 * @param hidden
 */
export function manageScrollBar(hidden) {
    const $body = document.getElementsByTagName('body')[0];
    const oScrollWidth = getScrollbarWidth();
    const hiddenStyle = `width: calc(100% - ${oScrollWidth}px);overflow: hidden`;
    if (hidden) {
        $body.setAttribute('style', hiddenStyle)
    } else {
        $body.removeAttribute('style')
    }
}

/**
 * 保留2位小数
 * @param num
 * @param precision
 * @returns {*}
 */
export function toFixed(num, precision = 2) {
    // console.log('num,',num,'pre',precision)
    if (typeof num == 'string') {
        num = Number(num)
    }
    return num.toFixed(precision)
}

export const calBatPercent = (value = 0) => {
    const numVal = Number(value) / 100;
    return `${numVal}%`
}

export const backTop = (id) => {
    const tar = id || '#app';
    document.querySelector(`${tar}`).scrollIntoView({
        behavior: 'smooth'
    })
}

/**
 * 去掉负号和e
 * @param val
 * @returns {string}
 */
const removeMius = (val) => {
    // const rval = String(val).replace(/[^\d]/g,'');
    return String(val).replaceAll('-', '');
}
/**
 * 格式化数据
 * @param val
 * @param decimal
 * @returns {string|*}
 */

export const formatPrice = (val, decimal) => {
    // debugger
    const sPrice = removeMius(val);
    const maxDecimal = decimal || 4; // 小数
    const maxIntLength = 9; // 最大整数位数
    const maxLength = 14; //  最大长度

    if (sPrice.includes('.')) {
        const arr = sPrice.split('.');
        if (arr[0].length > maxIntLength) {
            return arr[0].slice(0, maxIntLength) + '.' + arr[1].slice(0, maxDecimal);
        } else if (arr[1].length > maxDecimal) {
            return arr[0] + '.' + arr[1].slice(0, maxDecimal);
        } else if (sPrice.length >= maxLength) {
            sPrice.slice(0, maxLength);
        }
        return sPrice;
    } else if (sPrice.length >= maxIntLength) {
        return sPrice.slice(0, maxIntLength);
    } else {
        return sPrice;
    }
}

/**
 * 手机端判断
 * @returns {boolean}
 */
export const isMobile = () => {
    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
        return true
    }
}


export function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * 小数位数
 * @param val
 * @returns {number}
 */
export const precisionCount = (val) => {
    let precision = 2;
    const nVal = Number(val);
    const sVal = String(val);
    if (nVal < 1) {
        const lastIndex = sVal.lastIndexOf('.');
        const lg = sVal.slice(lastIndex + 1);
        const calp = (lg.length) * 2 > 8 ? 8 : (lg.length) * 2;
        precision = Math.max(4, calp)
    } else if (sVal.includes(".")) {
        const lastIndex = sVal.lastIndexOf('.');
        const lg = sVal.slice(lastIndex + 1);
        precision = Math.min(4, lg * 2);
    }
    return precision
}

const isZero = (val) => {
    return val === 0 || val == '0' || val == '' || val == undefined || val == null
}

export const displayNum = (val, defaultPrecision = 4) => {
    const is_zero = isZero(val)
    if (is_zero) {
        return 0;
    }
    if (defaultPrecision) {
        return toFixed(val, defaultPrecision)
    }
    const precision = precisionCount(val);
    // console.log('precision',precision)
    return toFixed(val, precision)
}


/**
 * email格式验证
 * @param str ：email@163.com
 * @returns {boolean}
 */
export function is_Email(str) {
    const trimStr = str.trim();
    var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/;
    return reg.test(trimStr);
}


/**
 * mini address
 * @param address
 * @param num
 * @returns {string}
 */
export const addressTrimmed = (address, num = 4) => {
    if (!address) return address
    return address.slice(0, num) +
        ".." +
        address.slice(`-${num}`)
}

/**
 * 补0
 * @param n
 * @returns {string|*}
 */
export function addZeros(n) {
    const num = n + 1;
    if (num >= 1000) {
        return num;
    } else if (num >= 100 && num <= 999) {
        return '0' + num;
    } else if (num >= 10 && num <= 99) {
        return '00' + num;
    } else if (num >= 0 && num <= 9) {
        return '000' + num;
    }
}

export function getScrollTop() {
    return document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
}

/**
 * 文字缩略...
 * @param value
 * @param arg1
 * @returns {string}
 */
export const shrink = (value, arg1 = 50) => {
    if (!value) return '';
    return value.slice(0, arg1) + `...`
}
export const isValid = (val) => {
    if (val == 0 || val == '0') {
        return true;
    }
    return val !== null && val !== undefined && val !== '';
}

// 封装的函数，禁用页面滚动条
export function disableScroll() {
    document.body.style.overflow = 'hidden';
}

// 封装的函数，恢复页面滚动条
export function enableScroll() {
    document.body.style.overflow = '';
}

/**
 * 生成一个包含数字、字母（区分大小写）的重复极低的字符串
 * @param length
 * @returns {string}
 */
export function generateSecureRandomString(length = 16) {
    // 确保在支持crypto API的环境中运行
    if (!window.crypto || !window.crypto.getRandomValues) {
        throw new Error('Crypto API not supported.');
    }

    // 确保生成的字符串长度是有效的
    if (length < 1 || length > 256) {
        throw new Error('Invalid length. Length must be between 1 and 256.');
    }

    const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const randomBytesLength = length * charset.length;
    const randomBytes = new Uint8Array(randomBytesLength);

    // 生成随机值
    window.crypto.getRandomValues(randomBytes);

    // 解码为字符串
    let result = '';
    for (let i = 0; i < length; i++) {
        const index = randomBytes[i] % charset.length;
        result += charset[index];
    }

    return result;
}

/**
 * 生成随机数
 * @param min
 * @param max
 * @param precision
 * @returns {number}
 */
export function getRandomFloat(min, max, precision = 2) {
    // 确保 min 和 max 是有效的数值输入
    if (min >= max) {
        throw new Error('min must be less than max');
    }
    // 生成一个在[min, max]范围内的随机数
    let randomNum = Math.random() * (max - min) + min;

    // 根据精度对结果四舍五入
    randomNum = randomNum.toFixed(precision);

    // 将字符串转换回浮点数
    return parseFloat(randomNum);
}